package ar.edu.itba.jMEBowling.scenario;

import ar.edu.itba.jMEBowling.ShotSpecification;
import ar.edu.itba.jMEBowling.utils.Helpers;

import com.jme.bounding.BoundingSphere;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Node;
import com.jme.scene.shape.Sphere;
import com.jme.scene.state.MaterialState;
import com.jme.system.DisplaySystem;
import com.jmex.physics.DynamicPhysicsNode;
import com.jmex.physics.PhysicsSpace;
import com.jmex.physics.material.Material;

public class BowlingBall {

	private Sphere ball;
	private DynamicPhysicsNode ballNode;
	private final int zSamples = 30;
	private final int radialSamples = 30;
	private final float radius = 0.7f;
	private Material material;
	private Vector3f locationBackup;
	private Node rootNode;

	public BowlingBall(Vector3f pos, PhysicsSpace physicsSpace, Node rootNode,
			DisplaySystem displaySystem, String textureFile) {

		ball = new Sphere("ball", new Vector3f(0, 0, 0), zSamples,
				radialSamples, radius);
		ball.setModelBound(new BoundingSphere());
		ball.updateModelBound();
		ball.setCastsShadows(true);

		ballNode = physicsSpace.createDynamicNode();
		ballNode.setName("ball");
		ballNode.attachChild(ball);
		ballNode.generatePhysicsGeometry();
		ballNode.setMass(4f);
		Helpers.setTexture(ballNode, textureFile, displaySystem);
		material = Helpers.getMaterial("ballMaterial", 10f);
		MaterialState materialState = displaySystem.getRenderer()
				.createMaterialState();
		materialState.setAmbient(ColorRGBA.black);
		materialState.setDiffuse(new ColorRGBA(0.1f, 0.5f, 0.8f, 1.0f));
		materialState.setSpecular(ColorRGBA.white);
		materialState.setShininess(100);
		materialState.setEmissive(ColorRGBA.black);
		materialState.setEnabled(true);
		ballNode.setRenderState(materialState);
		// and update the geometry

		ballNode.setMaterial(material);
		ballNode.computeMass();
		ballNode.getLocalTranslation().set(pos);
		ballNode.updateRenderState();
		locationBackup = new Vector3f(pos);
		this.rootNode = rootNode;
		rootNode.attachChild(ballNode);
	}

	public void changeContactMaterial(Material contactedMaterial,
			float sliding, float bounciness) {
		Helpers.updateContactInfo(material, contactedMaterial, sliding,
				bounciness);
		ballNode.setMaterial(material);
	}

	public DynamicPhysicsNode getBallNode() {
		return ballNode;
	}

	public void dontMove() {
		ballNode.rest();
	}

	public void canMove() {
		ballNode.unrest();
	}

	public void shoot(ShotSpecification shotSpecification) {
		rootNode.attachChild(ballNode);
		canMove();
		ballNode.setLocalTranslation(shotSpecification.getShotDirection()
				.getLocalTranslation());
		ballNode.addForce(new Vector3f(shotSpecification.getXForce(),
				shotSpecification.getYForce(), shotSpecification.getZForce()));

	}

	public void reset() {

		ballNode.rest();
		ballNode.getLocalTranslation().set(new Vector3f(locationBackup));
		ballNode.setActive(true);
		ballNode.setLocalRotation(new Quaternion(new float[] { 0, 0, 0 }));
		ballNode.setLinearVelocity(new Vector3f(0, 0, 0));
		ballNode.setAngularVelocity(new Vector3f(0, 0, 0));

	}

	public Sphere getBall() {
		return ball;
	}

	public void setBall(Sphere ball) {
		this.ball = ball;
	}

	public Material getMaterial() {
		return material;
	}

	public void setMaterial(Material material) {
		this.material = material;
	}

	public int getZSamples() {
		return zSamples;
	}

	public int getRadialSamples() {
		return radialSamples;
	}

	public float getRadius() {
		return radius;
	}

	public void setBallNode(DynamicPhysicsNode ballNode) {
		this.ballNode = ballNode;
	}

}
